package com.zxpt.quetion.utils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 所在包：com.wenhe.demo.utils
 * 文件名：
 * 项目：testMybatis
 * 功能描述：
 * 修改人：Xlz
 * 修改时间：2020-04-26 15:50
 */
public class SqlUtil<T> {

    // 主键类型（数字和字符串）
    private final String NUMBER = "number";
    private final String VARCHAR = "varchar";
    private final String CHAR = "char";

    /**
     * 生成新增sql
     * @param clazz
     * @param t
     * @return
     */
    public String createInsertSql(Class<? super T> clazz, T t) {
        List<String> notNullFields = getNotNullFieldsWithId(clazz, t);
        String idType = getIdType(clazz);
        // 类名
        String className = clazz.getSuperclass().getSimpleName();
        // 表名
        String tableName = getColumnByField(className.substring(0,1).toLowerCase() + className.substring(1));
        String fieldStr = "";   // 字段字符串
        String valueStr = "";   // 值字符串
        if (notNullFields.size() > 0) {
            for (String fieldName : notNullFields) {
                String columnName = getColumnByField(fieldName);
                fieldStr = fieldStr + "," + columnName;
                valueStr = valueStr + ", #{item." + fieldName + "}";
            }
            // 判断主键id是否为空， 如果为空则设置主键值
            if (idType.equals(VARCHAR) || idType.equals(CHAR)) {
                try {
                    Field idField = clazz.getSuperclass().getDeclaredField("id");
                    idField.setAccessible(true);
                    Object idValue = idField.get(t);
                    if (idValue == null) {
                        idField.set(t, createPojoId());
                    }
                } catch (NoSuchFieldException e) {
                    System.out.println("该表主键名称不为id！");
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    System.out.println("设置主键值报错！");
                    e.printStackTrace();
                }
            }

        }
        fieldStr = fieldStr.substring(1);
        valueStr = valueStr.substring(1);
        String sql = "";
        sql = sql + "insert into " + tableName + "(" + fieldStr + ") values(" + valueStr + ")";

        return sql;
    }

    /**
     * 生成修改sql
     * @param clazz
     * @return
     */
    public String createUpdateAbsoluteSql(Class<? super T> clazz) {
        List<String> fieldsAll = getFieldsAll(clazz);
        // 类名
        String className = clazz.getSuperclass().getSimpleName();
        // 表名
        String tableName = getColumnByField(className.substring(0,1).toLowerCase() + className.substring(1));
        String fieldStr = "";   // 字段字符串
        if (fieldsAll.size() > 0) {
            for (String fieldName : fieldsAll) {
                String columnName = getColumnByField(fieldName);
                if (!fieldName.equals("id")) {
                    fieldStr = fieldStr + "," + columnName + " = #{item." + fieldName + "}";
                }
            }
        }
        fieldStr = fieldStr.substring(1);
        String sql = "";
        sql = sql + "update " + tableName + " set " + fieldStr + " where id = #{item.id}";
        return sql;
    }

    /**
     * 生成修改sql
     * @param clazz
     * @param t
     * @return
     */
    public String createUpdateSelectiveSql(Class<? super T> clazz, T t) {
        List<String> notNullFields = getNotNullFields(clazz, t);
        // 类名
        String className = clazz.getSuperclass().getSimpleName();
        // 表名
        String tableName = getColumnByField(className.substring(0,1).toLowerCase() + className.substring(1));
        String fieldStr = "";   // 字段字符串
        if (notNullFields.size() > 0) {
            for (String fieldName : notNullFields) {
                String columnName = getColumnByField(fieldName);
                if (!fieldName.equals("id")) {
                    fieldStr = fieldStr + "," + columnName + " = #{item." + fieldName + "}";
                }
            }
        }
        fieldStr = fieldStr.substring(1);
        String sql = "";
        sql = sql + "update " + tableName + " set " + fieldStr + " where id = #{item.id}";
        return sql;
    }


    public String createUpdateByMap(Class<? super T> clazz, T t, Map<String,String> queMap) {
        List<String> notNullFields = getNotNullFields(clazz, t);
        // 类名
        String className = clazz.getSuperclass().getSimpleName();
        // 表名
        String tableName = getColumnByField(className.substring(0,1).toLowerCase() + className.substring(1));
        String fieldStr = "";   // 字段字符串
        if (notNullFields.size() > 0) {
            for (String fieldName : notNullFields) {
                String columnName = getColumnByField(fieldName);
                if (!fieldName.equals("id")) {
                    fieldStr = fieldStr + "," + columnName + " = #{item." + fieldName + "}";
                }
            }
        }
        fieldStr = fieldStr.substring(1);
        String sql = "";
        sql = sql + "update " + tableName + " set " + fieldStr + " where ";
        Iterator<Map.Entry<String, String>> iterator = queMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            sql = sql +entry.getKey() +" = "+"'"+entry.getValue()+"'";
            if(iterator.hasNext()){
                sql = sql + " and ";
            }
        }
        return sql;
    }




    /**
     * 获取对象所有的字段
     * @param clazz
     * @return
     */
    private List<String> getFieldsAll(Class<? super T> clazz) {
        List<String> filedList = new ArrayList<>();
        Field[] fields = clazz.getSuperclass().getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            filedList.add(name);
        }
        return filedList;
    }

    /**
     * 获取对象所有的非空字段
     * @param clazz
     * @param t
     * @return
     */
    private List<String> getNotNullFields(Class<? super T> clazz, T t) {
        List<String> fieldList = new ArrayList<>();
        Field[] fields = clazz.getSuperclass().getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object value = field.get(t);
                if (value != null) {
                    String name = field.getName();
                    fieldList.add(name);
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return fieldList;
    }

    /**
     * 获取对象所有的非空字段
     * @param clazz
     * @param t
     * @return
     */
    private List<String> getNotNullFieldsWithId(Class<? super T> clazz, T t) {
        List<String> fieldList = new ArrayList<>();
        Field[] fields = clazz.getSuperclass().getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                String fieldName = field.getName();
                if (fieldName.equals("id")) {
                    fieldList.add(fieldName);
                } else {
                    Object value = field.get(t);
                    if (value != null) {
                        fieldList.add(fieldName);
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return fieldList;
    }

    /**
     * 获取主键类型
     * @param clazz
     * @return
     */
    private String getIdType(Class<? super T> clazz) {
        Field[] fields = clazz.getSuperclass().getDeclaredFields();
        String type = "java.lang.Integer";
        for (Field field : fields) {
            String name = field.getName();
            if (name.equals("id")) {
                Class<?> fieldType = field.getType();
                type = fieldType.getName();
                System.out.println(type);
            }
        }
        if (type.equals("java.lang.Integer") || type.equals("java.lang.Long")) {
            return NUMBER;
        } else {
            return VARCHAR;
        }
    }

    /**
     * 驼峰转下划线（首字母默认小写）
     * @param str
     * @return
     */
    private String getColumnByField(String str) {
        char[] chars = str.toCharArray();
        int length = chars.length;
        String underlineStr = "";
        for (int i=0; i< length; i++) {
            char current = chars[i];
            String currentStr = current + "";
            if (i==0) {
                underlineStr = current + "";
                underlineStr = underlineStr.toLowerCase();
            } else {
                if (current >= 65 && current <= 90) {
                    underlineStr = underlineStr + "_" + currentStr.toLowerCase();
                } else {
                    underlineStr = underlineStr + currentStr;
                }
            }
        }
        return underlineStr;
    }

    /**
     * 生成对象主键
     * @return
     */
    private String createPojoId() {
//        String id = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
        String id = UUID.randomUUID().toString().toUpperCase();
        return id;
    }
}
